package com.chatroom.ws;

import com.chatroom.enity.Message;
import com.chatroom.utils.MessageUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 计算机系 ITAEM 纱雾休比我老婆
 * @Description
 * @date 2022/8/9 20:18
 */
@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)
@Component
public class ChatEndpoint {

    //存储每个客户端对象对应的ChatEndpoint对象
    private static Map<String,ChatEndpoint> onLineUsers = new ConcurrentHashMap<>();
    //声明session对象，通过该对象可以发送消息给指定的用户
    private Session session;
    //声明一个HttpSession对象，可用于获取之前存储的用户名
    private HttpSession httpSession;

    /**
     * 连接建立时被调用
     * @param session
     * @param config
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config){
        this.session = session;
        //获取httpSession对象
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());

        //从httpSession中获取用户名
        String username = (String) httpSession.getAttribute("user");

        //将当前对象存储到容器内
        onLineUsers.put(username,this);

        //将当前在线用户名的用户名推送给所有的客户端
        //1.获取消息
        String message = MessageUtil.getMessage(true, null, onLineUsers.keySet());
        //2.调用方法进行系统消息的推送
        System.out.println(message);
        broadcastAllUsers(message);
    }

    private void broadcastAllUsers(String message){
        Set<String> names = onLineUsers.keySet();
        for (String name : names){
            ChatEndpoint chatEndpoint = onLineUsers.get(name);
            try {
                chatEndpoint.session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 接收到客户端发送的数据时被调用
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session){
        System.out.println(message);
        try {
            //将message转换为message对象
            ObjectMapper mapper = new ObjectMapper();
            Message mess = mapper.readValue(message, Message.class);
            //获取要发送给的用户
            String toName = mess.getToName();
            //获取消息数据
            String data = mess.getMessage();
            //获取当前登录的用户
            String username = (String) httpSession.getAttribute("user");
            //获取推送给指定用户的消息数据格式的数据
            String result = MessageUtil.getMessage(false, username, data);
            //发送数据
            onLineUsers.get(toName).session.getBasicRemote().sendText(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接关闭时被调用
     * @param session
     */
    @OnClose
    public void onClose(Session session){
        //从容器删除指定的用户
        onLineUsers.remove((String) httpSession.getAttribute("user"));
        //获取推送的消息
        String message = MessageUtil.getMessage(true, null, onLineUsers.keySet());
        System.out.println(message);
        broadcastAllUsers(message);
    }
}
